#!/bin/bash

# 根据平台（linux mac）选择相应能用的包管理（如：brew apt dpkg pacman yay yum 等）进行命令行安装
function install_with_package() {
    # local pkg="$1"
    # 获取多参数
    local pkg=""
    # 如果是mac
    case "${OSTYPE}" in
        # *'linux'*   ) arg_start_num=1     ;;
        *'darwin'*  ) arg_start_num=1    ;; # 由于mac会传入当前脚本路径作为$0
        *           ) arg_start_num=0    ;;
    esac
    for ((arg_index=arg_start_num; arg_index<=$#; arg_index++)); do
        pkg+="${!arg_index} "  # 间接引用获取参数
    done
    SHELL_PLATFORM='unknown';
    shellostypestring=`echo $OSTYPE`;
    ## 从字符串中识别shell系统类型
    case "${shellostypestring}" in
        *'linux'*   ) 
            SHELL_PLATFORM='linux' 
            # 检测发行版
            local distro=""
            if [[ -f /etc/os-release ]]; then
                distro=$(grep '^ID=' /etc/os-release | cut -d= -f2 | tr -d '"')
            fi
            case "$distro" in
                debian|ubuntu|raspbian)
                    if command -v apt &> /dev/null; then
                        echo "🟢 Debian-based detected. Installing with apt..."
                        xeval "sudo apt update"
                        xeval "sudo apt install -y $pkg"
                    elif command -v apt-get &> /dev/null; then
                        echo "🟢 Debian-based (legacy) detected. Installing with apt-get..."
                        xeval "sudo apt-get update"
                        xeval "sudo apt-get install -y $pkg"
                    fi
                    ;;
                fedora|rhel|centos)
                    if command -v dnf &> /dev/null; then
                        echo "🟢 RedHat-based (modern) detected. Installing with dnf..."
                        xeval "sudo dnf install -y $pkg"
                    elif command -v yum &> /dev/null; then
                        echo "🟢 RedHat-based (legacy) detected. Installing with yum..."
                        xeval "sudo yum install -y $pkg"
                    fi
                    ;;
                arch|manjaro)
                    if command -v yay &> /dev/null; then
                        echo "🟢 Arch-based (AUR helper) detected. Installing with yay..."
                        xeval "yay -Sy --noconfirm $pkg"
                    elif command -v pacman &> /dev/null; then
                        echo "🟢 Arch-based detected. Installing with pacman..."
                        xeval "sudo pacman -Sy --noconfirm $pkg"
                    fi
                    ;;
                opensuse*|sles)
                    if command -v zypper &> /dev/null; then
                        echo "🟢 openSUSE detected. Installing with zypper..."
                        xeval "sudo zypper install -y $pkg"
                    fi
                    ;;
                alpine)
                    if command -v apk &> /dev/null; then
                        echo "🟢 Alpine detected. Installing with apk..."
                        xeval "sudo apk add $pkg"
                    fi
                    ;;
                *)
                    ;;
            esac
            return $?
            ;;
        *'darwin'*  ) # macOS (Homebrew)
            SHELL_PLATFORM='osx'  
            if command -v port &> /dev/null; then
                echo "🟢 macOS detected. Installing with MacPorts..."
                xeval "sudo port install $pkg"
            elif command -v brew &> /dev/null; then
                echo "🟢 macOS detected. Installing with Homebrew..."
                xeval "brew install $pkg"
                return $?
            else
                echo "❌ Homebrew not found. Please install Homebrew first:"
                echo "https://brew.sh/  or https://www.macports.org/install.php#installing"
                return 1
            fi
            ;;
        *'bsd'*     ) 
            SHELL_PLATFORM='bsd'      
            ;;
        *) 
            echo "未知系统类型"
        ;;
    esac
    # 通用包管理器检测 (作为后备)
    local managers=("dpkg" "rpm" "dnf")
    for manager in "${managers[@]}"; do
        if command -v "$manager" &> /dev/null; then
            echo "⚠️  Using low-level $manager installer (may require manual dependency handling)"
            echo "📦 Package file expected: ${pkg}.${manager}"
            return 1
        fi
    done
    echo "❌ No supported package manager found for Linux distribution: $distro"
    return 1
}

# 添加环境变量
function add_path_env() {
    # 定义要添加的软件目录
    # SOFTWARE_DIR="/path/to/your/software/bin"
    TARGET_PATH="$1"
     if [ -z "$TARGET_PATH" ]; then
        xecho "ERROR" "错误：请指定要添加的软件目录路径作为参数"
        # echo "用法: $0 /path/to/your/software"
        exit 1
    fi
    
    # 安全扩展波浪号路径（关键修复）
    if [[ "$TARGET_PATH" == ~* ]]; then
        expanded_path=$(eval echo "$TARGET_PATH")
        if [ "$expanded_path" != "$TARGET_PATH" ]; then
            TARGET_PATH="$expanded_path"
            xecho "DEBUG" "扩展波浪号路径: $TARGET_PATH"
        fi
    fi

    # 检查路径是否存在
    if [ ! -e "$TARGET_PATH" ]; then
        xecho "ERROR" "错误：指定路径不存在: $TARGET_PATH"
        exit 1
    fi
    
    # 如果是文件，则取其所在目录
    if [ -f "$TARGET_PATH" ]; then
        SOFTWARE_DIR=$(dirname "$TARGET_PATH")
        xecho “INFO” "检测到文件路径，将使用其所在目录: $SOFTWARE_DIR"
    elif [ -d "$TARGET_PATH" ]; then
        SOFTWARE_DIR="$TARGET_PATH"
    else
        xecho “ERROR” "错误：不支持的路径类型: $TARGET_PATH"
        exit 1
    fi

    # 确保路径是绝对路径
    case $SOFTWARE_DIR in
        /*) ;;
        *) 
            xecho "WARNING" "警告：路径不是绝对路径，将转换为绝对路径"
            SOFTWARE_DIR=$(realpath "$SOFTWARE_DIR" 2>/dev/null || echo "$(pwd)/$SOFTWARE_DIR")
            ;;
    esac

    # 获取当前Shell类型（取基名）
    current_shell=$(basename "$SHELL")
    xecho "INFO" "获取当前Shell类型: $current_shell"
    # 确定配置文件路径
    case "$current_shell" in
        bash)
            config_file="$HOME/.bashrc"
            ;;
        zsh)
            config_file="$HOME/.zshrc"
            ;;
        sh|dash|ksh)
            # 注意：sh可能是其他Shell的链接，使用通用配置文件
            config_file="$HOME/.profile"
            ;;
        *)
            xecho "ERROR" "Unsupported shell: $current_shell"
            exit 1
            ;;
    esac

    # 检查目录是否已在PATH中
    path_contains_dir() {
        echo "$PATH" | tr ':' '\n' | grep -qFx "$1"
    }

    # 主逻辑
    if path_contains_dir "$SOFTWARE_DIR"; then
        xecho "INFO" "目录已存在于PATH中: $SOFTWARE_DIR"
    else
        # 备份配置文件
        cp "$config_file" "${config_file}.bak-$(date +%Y%m%d%H%M%S)"
        
        # 添加环境变量配置
        echo "添加目录到PATH: $SOFTWARE_DIR"
        echo "export PATH=\"\$PATH:$SOFTWARE_DIR\"" >> "$config_file"
        
        # 提示用户
        echo '''
        配置已更新！请执行以下命令生效：
        立即生效: source "$config_file"
        或重启终端
        备份文件: ${config_file}.bak-*
        '''
    fi
}

# 示例：如何获取文件的MD5值（可以在软件列表定义中添加）
function get_file_md5() {
    local file_path="$1"
    if [ -f "$file_path" ]; then
        md5sum "$file_path" | cut -d' ' -f1
    else
        echo ""
    fi
}

# 增强的下载函数，支持多线程下载、断点续传、错误重试和完整性校验
function enhanced_download() {
    local url="$1"
    local output_path="$2"
    local expected_md5="${3:-}"       # 可选的MD5校验值
    local max_retries="${4:-3}"        # 重试次数，默认3次
    local timeout="${5:-30}"           # 超时时间（秒），默认30秒
    local connections="${6:-4}"        # 连接数/线程数，默认4个
    
    xecho "DEBUG" "开始下载: $url -> $output_path"
    xecho "DEBUG" "重试次数: $max_retries, 超时: ${timeout}s, 连接数: $connections, MD5校验: ${expected_md5:-无}"
    
    # 创建输出目录
    local output_dir=$(dirname "$output_path")
    mkdir -p "$output_dir"
    
    # 尝试不同的下载工具（按优先级排序）
    local download_success=false
    local retry_count=0
    
    while [ $retry_count -lt $max_retries ] && [ "$download_success" = false ]; do
        retry_count=$((retry_count + 1))
        xecho "INFO" "下载尝试 $retry_count/$max_retries"
        
        # 检查文件是否已部分下载
        local resume_flag=""
        if [ -f "$output_path" ]; then
            local current_size=$(stat -c%s "$output_path" 2>/dev/null || stat -f%z "$output_path" 2>/dev/null)
            xecho "DEBUG" "检测到已存在部分文件: $output_path (大小: $current_size bytes)"
            resume_flag="true"
        fi
        
        # 尝试使用不同的下载工具（优先使用支持多线程的）
        if command -v aria2c &>/dev/null; then
            # aria2c - 功能最强大的下载工具，支持多线程
            xecho "DEBUG" "使用 aria2c 多线程下载 (连接数: $connections)"
            local aria2c_args=(
                "$url"
                "-o" "$(basename "$output_path")"
                "--dir" "$output_dir"
                "--timeout=$timeout"
                "--connect-timeout=$timeout"
                "--max-tries=$max_retries"
                "--max-file-not-found=3"
                "--check-certificate=false"
                "--allow-overwrite=true"
                "--auto-file-renaming=false"
                "--split=$connections"
                "--max-connection-per-server=$connections"
                "--min-split-size=1M"
            )
            
            if [ "$resume_flag" = "true" ]; then
                aria2c_args+=("--continue=true")
            fi
            
            # 在输出目录中执行aria2c命令
            if (cd "$output_dir" && aria2c "${aria2c_args[@]}"); then
                download_success=true
            fi
            
        # elif command -v axel &>/dev/null; then
        #     # axel - 轻量级多线程下载工具
        #     xecho "DEBUG" "使用 axel 多线程下载 (连接数: $connections)"
        #     local axel_args=(
        #         "-n" "$connections"
        #         "-a" # 显示进度条
        #         "-o" "$output_path"
        #         "--timeout=$timeout"
        #         "--max-redirect=5"
        #     )
            
        #     if [ "$resume_flag" = "true" ]; then
        #         axel_args+=("-c") # 继续下载
        #     fi
            
        #     if axel "${axel_args[@]}" "$url"; then
        #         download_success=true
        #     fi
            
        elif command -v wget &>/dev/null; then
            # wget - 支持断点续传但不支持多线程
            xecho "DEBUG" "使用 wget 下载 (单线程)"
            local wget_args=(
                "--no-check-certificate"
                "--timeout=$timeout"
                "--tries=$max_retries"
                "-O" "$output_path"
            )
            
            if [ "$resume_flag" = "true" ]; then
                wget_args+=("-c")  # 继续部分下载
            else
                wget_args+=("-nc") # 不要覆盖现有文件
            fi
            
            if wget "${wget_args[@]}" "$url"; then
                download_success=true
            fi
            
        elif command -v curl &>/dev/null; then
            # curl - 支持断点续传但不支持多线程
            xecho "DEBUG" "使用 curl 下载 (单线程)"
            local curl_args=(
                "--insecure"
                "--connect-timeout" "$timeout"
                "--max-time" "$((timeout * 10))"
                "--retry" "$max_retries"
                "--retry-delay" "2"
                "--output" "$output_path"
            )
            
            if [ "$resume_flag" = "true" ]; then
                curl_args+=("-C" "-")  # 继续部分下载
            fi
            
            if curl "${curl_args[@]}" "$url"; then
                download_success=true
            fi
            
        else
            xecho "ERROR" "没有找到可用的下载工具 (aria2c, axel, wget, curl)"
            return 1
        fi
        
        # 检查下载是否成功
        if [ "$download_success" = true ] && [ -f "$output_path" ]; then
            # 验证文件完整性
            if [ -n "$expected_md5" ]; then
                xecho "DEBUG" "进行MD5校验..."
                local actual_md5=$(md5sum "$output_path" | cut -d' ' -f1)
                if [ "$actual_md5" != "$expected_md5" ] && ["$expected_md5" != "/"]  && [ -n "$expected_md5" ]; then
                    xecho "WARNING" "MD5校验失败: 期望 $expected_md5, 实际 $actual_md5"
                    download_success=false
                    rm -f "$output_path"  # 删除损坏的文件
                else
                    xecho "SUCCESS" "MD5校验通过"
                fi
            fi
            
            # 检查文件是否为空
            if [ ! -s "$output_path" ]; then
                xecho "WARNING" "下载的文件为空"
                download_success=false
                # rm -f "$output_path"
            fi
        fi
        
        if [ "$download_success" = false ]; then
            if [ $retry_count -lt $max_retries ]; then
                xecho "WARNING" "下载失败，将在 2 秒后重试..."
                sleep 2
            else
                xecho "ERROR" "下载失败: $url (尝试 $max_retries 次)"
                echo "$output_path"
                return 1
            fi
        fi
    done
    
    if [ "$download_success" = true ]; then
        xecho "SUCCESS" "下载完成: $output_path"
        echo "$output_path"
        return 0
    else
        return 1
    fi
}

# 修改原有的 download_software_file 函数
function download_software_file(){
    xecho "Debug" "=== download_software_file() --install_fun.sh ==="
    
    if [ $# -lt 2 ]; then
        echo "用法: download_software_file <应用名称> <FILE_URL>  [MD5校验值] [保存路径]"
        echo "示例: download_software_file MyApp https://example.com/app.AppImage $HOME/Downloads"
        return 1
    fi

    local file_name="$1"
    local file_download_url="$2"
    local expected_md5="${3:-}"
    local output_path="${4:-}"
    # 设置默认下载目录
    local base_download_file_save_path="$HOME/Downloads/Softwares"
    mkdir -p "$base_download_file_save_path"
    
    # 如果没有指定输出路径，使用默认路径和URL中的文件名
    if [ "$output_path" == "" ]; then
        xecho "Debug" "output_path 空"
        local filename=$(basename "$file_download_url")
        output_path="$base_download_file_save_path/$filename"
    # else
    #     xecho "DEBUG" "output_path 11=$output_path "
    fi
    xecho "DEBUG" "output_path=$output_path "
    restart_down_flag=1 # 是否开始或重新下载
    # 判断是否文件存在
    if [[ ! -f "$output_path" ]]; then
        xecho "Debug" "文件 $output_path 不存在！现在开始下载..."
        xecho "INFO" "$file_download_url ==> $output_path"
        # ehco "$output_path"
        # restart_down_flag=0
    else 
        # 是否有MD5 有则检查
        now_save_file_MD5=$(get_file_md5 $output_path | tail -n 1)
        xecho "INFO" "now_save_file_MD5=$now_save_file_MD5"
        if [ "$now_save_file_MD5" = "$expected_md5" ] && [ -n "$expected_md5" ] && ["$expected_md5" != "/"] ; then
            restart_down_flag=0
            xecho "INFO" "MD5校验通过已存在文件完整"
        fi
    fi
    xecho "Debug" "restart_down_flag=${restart_down_flag}"
    if [ $restart_down_flag -eq 1 ];then
        xecho "Debug" "文件使用增强的下载函数 enhanced_download " 
        # 使用增强的下载函数
        enhanced_download "$file_download_url" "$output_path" "$expected_md5"
    else
        echo "$output_path"
    fi
}

## 下载
function download_software_filev1(){
    xecho "Debug" "=== download_software_file() --install_fun.sh ==="
    # 检查参数数量
    if [ $# -ne 2 ]; then
        # echo "用法: $0 <应用名称> <AppImage_URL>"
        echo "用法: download_software_file <应用名称> <FILE_URL> <保存目录>"
        # echo "示例: $0 MyApp https://example.com/app/release/appname-latest.AppImage"
        echo "示例: download_software_file MyApp https://example.com/app/release/appname-latest.AppImage $HOME/Downloads"
        exit 1
    fi

    file_name=$1
    file_download_url=$2
    # xecho "Debug" "file_download_url = $file_download_url"
    base_download_file_save_path="$HOME/Downloads/Softwares"
    if [[ ! -d "$base_download_file_save_path" ]]; then # 文件夹不存在
        mkdir -p "$base_download_file_save_path"
    fi

    # # 检查是否以root运行
    # if [ "$(id -u)" -ne 0 ]; then
    #     echo "错误：需要root权限写入/opt目录"
    #     echo "请使用sudo运行此脚本"
    #     exit 1
    # fi

    # if ! wget -q --show-progress -O "${APP_NAME}.AppImage" "$APPIMAGE_URL"; then
    #     echo "下载失败！请检查URL和网络连接"
    #     exit 1
    # fi
  
    # 检查当前系统有什么下载软件

    # 判断参数是否为空
    if [ ! -n "$3" ]; then
        xecho "Debug" "参数为空!"
        file_name=`echo $file_download_url | awk -F'/' '{print $NF}'`
        xecho "Debug" "file_name = $file_name"
        # save_file_path="$download_file_save_path/$file_name"
        full_save_file_path="$base_download_file_save_path/$file_name"
    else
        xecho "Debug" "参数不为空!"
        full_save_file_path=$3
    fi
    xecho "Debug" "full_save_file_path = $full_save_file_path"
    if [ ! -s "$full_save_file_path" ]; then # 判断是否文件存在且非空
        xecho "Debug" "警告：文件 $full_save_file_path 是空的。 删除..."
        xeval "rm -f $full_save_file_path"
    fi
    # 判断是否文件存在
    if [[ ! -f "$full_save_file_path" ]]; then
        xecho "Debug" "文件 $full_save_file_path 不存在！现在开始下载..."
        xecho "INFO" "$file_download_url ==> $full_save_file_path"
        if [[  -x "$(which axel)" ]]; then
            xecho "Debug" "使用axel下载 $file_download_url"
            xeval "axel -n 1 -a --output $full_save_file_path $file_download_url"
        elif [[  -x "$(which wget)" ]]; then 
            xecho "Debug" "使用wget下载 $file_download_url"
            # wget https://evermeet.cx/ffmpeg/ffmpeg-113507-gf6b7b473d4.zip 
            # wget -c "$file_download_url"
            xeval "wget --no-check-certificate -c -O  '$full_save_file_path' '$file_download_url'"
            # xeval "wget -c -O  '$full_save_file_path' '$file_download_url'"
            # wget -b -c "$file_download_url" # 后台下载+断点续传
        else
            xecho "Debug" "使用curl下载 $file_download_url --> $full_save_file_path"
            # curl -C -# -R -O -I "$file_download_url" 
            xeval "curl   '$file_download_url' -o '$full_save_file_path'" # 显示下载进度、断点下载
            # cd $base_download_file_save_path
            # xeval "cd $base_download_file_save_path ; curl  -O '$file_download_url' " # 显示下载进度、断点下载
            # -O 将文件下载到当前目录下
            # -o 将文件 下载到 download 目录下，并重命名为 test.txt
            # -# 显示下载进度
            # -C 断点续传
            # [Linux 中三个下载工具-wget curl axel - 知乎](https://zhuanlan.zhihu.com/p/451426230)
        fi
    else 
        xecho "INFO" "文件 $full_save_file_path 存在！"
    fi
    if [ ! -s "$full_save_file_path" ]; then # 判断是否文件存在且非空
        xecho "Debug" "警告：文件 $full_save_file_path 是空的。 删除..."
        # xeval "rm -f $full_save_file_path"
        return 0
    else 
        echo "${full_save_file_path}"
    fi
    
}


# #    / **  
# #    *  下载安装函数
# #    */ 
function get_install_software_down_url() { # 下载文件
    xecho "Debug" "get_install_software_down_url() -- install_fun.sh"
    # software_offical_url=""
    software="$1"
    # file_download_url=""
    count=0
    for ((software_id = 0; software_id < ${#software_name[@]}; software_id++)); do
        # xecho "Debug" "software = $software, software_id = $software_id <=> ${software_name[$software_id]}"
        if [[ "$software" == "${software_name[$software_id]}" ]]; then  # 找到
            # software_offical_url=${software_url[$software_id]}  # 软件官网或下载地址
            # file_download_url=${software_down_url[$software_id]} # 软件指定下载地址
            # echo "${software_name[$software_id]}"  # 软件名
            # echo "${software_check[$software_id]}"  # 软件检查
            # echo "${software_descriptions[$software_id]}"  # 描述
            # echo "${software_url[$software_id]}"  # 软件官网或下载地址
            echo "${software_down_url[$software_id]}" # 软件指定下载地址
            break; # 找到，执行完则立即退出循环
        # else 
        #     xecho "Debug" "没找到 $software "
        fi
        count=$(($count+1))
    done
    # xecho "Debug" "count = $count，software_offical_url =$software_offical_url，file_download_url== $file_download_url"
    if [ $count -ge ${#software_name[@]} ]; then  # 遍历一遍没找到
        xecho "ERROR" "未知软件: $software"
        exit 1
    fi
}

function install_software_fun1() { # 下载文件
    xecho "DEBUG" "install_software_fun1 ---install_fun.sh"
    software=$1
    # xecho "DEBUG" "software=$software"
    local install_cmd=""
    for ((arg_index=2; arg_index<=$#; arg_index++)); do
        install_cmd+="${!arg_index} "  # 间接引用获取参数
    done
    xecho "DEBUG" "software =${software} , install_cmd =${install_cmd}"
    software_offical_url=""
    file_download_url=""
    count=0
    for ((software_id = 0; software_id < ${#software_name[@]}; software_id++)); do
        # xecho "Debug" "software = $software, software_id = $software_id <=> ${software_name[$software_id]}"
        if [[ "$software" == "${software_name[$software_id]}" ]]; then  # 找到
            software_offical_url=${software_url[$software_id]}  # 软件官网或下载地址
            file_download_url=${software_down_url[$software_id]} # 软件指定下载地址
            file_md5=${software_file_md5[$software_id]} # 
            break; # 找到，执行完则立即退出循环
        # else 
        #     xecho "Debug" "没找到 $software "
            # xecho "Debug" "software = $software, software_id = $software_id <=> ${software_name[$software_id]}"
        fi
        count=$(($count+1))
    done
    xecho "Debug" "count =${count} ,software_offical_url =${software_offical_url}  ,file_download_url== $file_download_url"
    if [ $count -ge ${#software_name[@]} ]; then  # 遍历一遍没找到
        xecho "ERROR" "未知软件: $software"
        exit 1
    fi
    # 快速查找到

    # 使用安装包管理器安装软件
    # install_with_package $software

    # 进行下载
    # download_software_file $software $file_download_url $file_md5
    full_save_file_path=$(download_software_file $software $file_download_url $file_md5 | tail -n 1) # 下载
    xecho "DEBUG" "full_save_file_path =$full_save_file_path "

    if [ ! -s "$full_save_file_path" ]; then # 判断是否文件存在且非空
        xecho "Debug" "警告：文件 $full_save_file_path 是空的。 删除..."
        xeval "rm -f $full_save_file_path"
        return 0
    else 
        xecho "Debug" "${full_save_file_path}下载成功。"
        # if [ -z "$install_cmd"  ]; then # 判断是否有后续命令有则执行
        if [ "$install_cmd" == ""  ]; then # 判断是否有后续命令有则执行
            xecho "Debug" "install_cmd 是空的。"
        else
            xecho "Debug" "$install_cmd 非空的。 执行..."
            # 执行命令
            xeval "$install_cmd"
        fi
        echo ${full_save_file_path}
    fi
}

# 根据后缀使用不同解压命令解压
function auto_extract_file(){
    xecho "DEBUG" "auto_extract_file() ---install_fun.sh"
    origin_file_path=$1 # 解压原件
    target_file_path=$2 # 解压目标地址
    if [ ! -n "$target_file_path" ]; then # 判断参数是否为空
        # target_file_path="$HOME/Downloads"
        # origin_file_path_no_ext="${origin_file_path%.*}"
        # 先尝试移除 .tar.gz 后缀
        origin_file_path_no_ext="${origin_file_path%.tar.gz}"
        # 如果移除失败（文件名不以 .tar.gz 结尾），则移除最后一个后缀
        if [ "$origin_file_path_no_ext" = "$origin_file_path" ]; then
            origin_file_path_no_ext="${origin_file_path%.*}"
        fi
        if [ -z "$origin_file_path_no_ext" ]; then
            echo "错误：移除后缀后路径为空（原始路径：$file_path）"
            return 1
        else
            target_file_path=$origin_file_path_no_ext
            if [ ! -d "$target_file_path" ]; then
                xeval "mkdir -p -- $target_file_path"
            fi
        fi
    fi
    xecho "INFO" "解压到: $origin_file_path ==> $target_file_path"
    # 判断是什么文件，使用不同解压命令解压
    ext_name=`echo $origin_file_path | awk -F'/' '{print $NF}' | awk -F'.' '{print $NF}' `
    echo "[Debug] ext_name = $ext_name"
    case $ext_name in
        'zip')   
            xecho "Debug" "$origin_file_path 是 *.zip"
            xeval "unzip -d '$target_file_path'  '$origin_file_path'"
       ;;
        '.tar.gz' | 'gz' ) 
            echo "[Debug] $origin_file_path 是*.tar.gz"
            # 解压到指定目录
            xeval "tar zxf $origin_file_path -C '$target_file_path'"
        ;;
        *) 
            xecho "INFO" "$origin_file_path 是未知格式不知道如何解压"
        ;;
    esac
    echo "${target_file_path}"
}

# 下载文件（需解压，解压后多文件）解压到 指定位置文件夹 、移动指定文件夹到指定位置 下
function install_software_fun2() { 
    xecho "DEBUG" "install_software_fun2 ---install_fun.sh"
    software=$1
    move_extr_dir_file=$2 # 移动的目录（全目录或部分）源
    move_extr2target_path=$3 # 移动到的目的地目录
    extr2dir=$4 # 解压到的目录（选填）
    install_cmd=""
    # 处理第四个位置参数
    if [ "$extr2dir" == ";" ]; then
        extr2dir="" # 如果 $4 是分号，则不赋值或赋空值
        # 表示后面有需要执行的另外命令
        local install_cmd=""
        for ((arg_index=5; arg_index<=$#; arg_index++)); do
            install_cmd+="${!arg_index} "  # 间接引用获取参数
        done
    else
        extr2dir="$4" # 否则使用 $4 的值
    fi
    xecho "DEBUG" "software =$software , extr2dir =$extr2dir , move_extr_dir_file =$move_extr_dir_file ,move_extr2target_path =$move_extr2target_path"
    # file_download_url=$(get_install_software_down_url $software |tail -n 1) # 获取下载链接地址
    # xecho "DEBUG" "file_download_url =$file_download_url "

    software_offical_url=""
    file_download_url=""
    file_md5=""
    count=0
    for ((software_id = 0; software_id < ${#software_name[@]}; software_id++)); do
        # xecho "Debug" "software = $software, software_id = $software_id <=> ${software_name[$software_id]}"
        if [[ "$software" == "${software_name[$software_id]}" ]]; then  # 找到
            software_offical_url=${software_url[$software_id]}  # 软件官网或下载地址
            file_download_url=${software_down_url[$software_id]} # 软件指定下载地址
            file_md5=${software_file_md5[$software_id]} # 软件指定下载地址
            break; # 找到，执行完则立即退出循环
        # else 
        #     xecho "Debug" "没找到 $software "
            # xecho "Debug" "software = $software, software_id = $software_id <=> ${software_name[$software_id]}"
        fi
        count=$(($count+1))
    done
    xecho "Debug" "count =${count} ,software_offical_url =${software_offical_url}  ,file_download_url== $file_download_url"
    if [ $count -ge ${#software_name[@]} ]; then  # 遍历一遍没找到
        xecho "ERROR" "未知软件: $software"
        exit 1
    fi


    full_save_file_path2=$(download_software_file $software $file_download_url $file_md5 |tail -n 1) # 下载
    xecho "DEBUG" "full_save_file_path2 =$full_save_file_path2 "
    extract_reslut_save_path=$(auto_extract_file $full_save_file_path2 $extr2dir |tail -n 1)   # 解压到指定位置
    xecho "DEBUG" "extract_reslut_save_path =$extract_reslut_save_path "
    
    # 拷贝文件到指定位置
    full_move_origin_path="$extract_reslut_save_path/$move_extr_dir_file"
    xecho "DEBUG" "full_move_origin_path = $full_move_origin_path "
    if [ ! -d "$move_extr2target_path" ]; then
        xeval "mkdir -p -- $move_extr2target_path"
    fi

    if [[ "$full_move_origin_path" == */./ ]]; then # 检查变量值是否以 "./" 结尾
        xecho "DEBUG" "提醒：路径末尾包含 './'，请注意处理！"
        clean_path="${full_move_origin_path%./}"  # 移除末尾的 ./
        clean_path="${clean_path%/}"  # 移除末尾的 /
        xecho "DEBUG" "$full_move_origin_path => $clean_path"
        # echo "清理后的路径：$clean_path"
        software_folder=$(basename "$clean_path") 
        xecho "DEBUG" "$software_folder =$software_folder"
        # 这里可以添加其他需要执行的命令
        xeval "sudo cp -r  $clean_path $move_extr2target_path"
        xeval "sudo chmod +x ${move_extr2target_path}/${software_folder}/*"
    else
        if [ -d "$full_move_origin_path" ];then
            xeval "sudo cp -r  $full_move_origin_path $move_extr2target_path"
            xeval "sudo chmod +x ${move_extr2target_path}/${move_extr_dir_file}/*"
        else
            xeval "sudo cp  $full_move_origin_path $move_extr2target_path"
            xeval "sudo chmod +x ${move_extr2target_path}/${move_extr_dir_file}"
        fi
    fi

    # 判断是否有额外要执行的命令
    
    if [ "$install_cmd" = "" ]; then
        xecho "DEBUG" "install_cmd 为空"
    else
        xeval "$install_cmd"
    fi
}

# 下载文件（需解压，解压后多文件）解压到 指定位置文件夹 、移动指定文件夹到指定位置 下
function open_url_with_brower() { 
    xecho "DEBUG" "open_url_with_brower ---install_fun.sh"
    software=$1
    xecho "DEBUG" "software =$software"
    file_download_url=$(get_install_software_down_url $software |tail -n 1) # 获取下载链接地址
    xecho "DEBUG" "file_download_url =$file_download_url "
    # full_save_file_path2=$(download_software_file $software $file_download_url |tail -n 1) # 下载
    # xecho "DEBUG" "full_save_file_path2 =$full_save_file_path2 "
    xeval "open $file_download_url"
}

# 下载文件（需解压，解压后多文件）解压到 指定位置文件夹 、移动指定文件夹到指定位置 下
function install_software_source_fun1() { 
    xecho "DEBUG" "install_software_source_fun1 ---install_fun.sh"
    software=$1
    # install_source_cmd=$2 # 安装命令
    local install_source_cmd=""
    for ((arg_index=2; arg_index<=$#; arg_index++)); do
        install_source_cmd+="${!arg_index} "  # 间接引用获取参数
    done
    xecho "DEBUG" "software =$software , install_source_cmd =$install_source_cmd "
    file_download_url=$(get_install_software_down_url $software |tail -n 1) # 获取下载链接地址
    xecho "DEBUG" "file_download_url =$file_download_url "

    software_offical_url=""
    file_download_url=""
    file_md5=""
    count=0
    for ((software_id = 0; software_id < ${#software_name[@]}; software_id++)); do
        # xecho "Debug" "software = $software, software_id = $software_id <=> ${software_name[$software_id]}"
        if [[ "$software" == "${software_name[$software_id]}" ]]; then  # 找到
            software_offical_url=${software_url[$software_id]}  # 软件官网或下载地址
            file_download_url=${software_down_url[$software_id]} # 软件指定下载地址
            file_md5=${software_file_md5[$software_id]} # 软件指定下载地址
            break; # 找到，执行完则立即退出循环
        # else 
        #     xecho "Debug" "没找到 $software "
            # xecho "Debug" "software = $software, software_id = $software_id <=> ${software_name[$software_id]}"
        fi
        count=$(($count+1))
    done
    xecho "Debug" "count =${count} ,software_offical_url =${software_offical_url}  ,file_download_url== $file_download_url"
    if [ $count -ge ${#software_name[@]} ]; then  # 遍历一遍没找到
        xecho "ERROR" "未知软件: $software"
        exit 1
    fi


    full_save_file_path2=$(download_software_file $software $file_download_url $file_md5 |tail -n 1) # 下载
    xecho "DEBUG" "full_save_file_path2 =$full_save_file_path2 "
    extr2dir=""
    extract_reslut_save_path=$(auto_extract_file $full_save_file_path2 $extr2dir |tail -n 1)   # 解压到指定位置
    xecho "DEBUG" "extract_reslut_save_path =$extract_reslut_save_path "
    
    # 执行命令
    # xeval "$install_source_cmd"
    if [ ! -s "$full_save_file_path2" ]; then # 判断是否文件存在且非空
        xecho "Debug" "警告：文件 $full_save_file_path2 是空的。 删除..."
        # xeval "rm -f $full_save_file_path"
        return 0
    else 
        xecho "Debug" "${full_save_file_path2}下载成功。"
        # if [ -z "$install_source_cmd"  ]; then # 判断是否有后续命令有则执行
        if [ "$install_source_cmd" = ""  ]; then # 判断是否有后续命令有则执行
            xecho "Debug" "install_source_cmd 是空的。"
        else
            xecho "Debug" "$install_source_cmd 非空的。 执行..."
            # 执行命令
            xeval "$install_source_cmd"
        fi
    fi
    
}